home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / xrobots / actions.c next >
C/C++ Source or Header  |  1995-05-03  |  8KB  |  317 lines

  1. /*
  2.  * actions.c  --  xrobots
  3.  * 
  4.  * Copyright 1989 Brian Warkentine
  5.  * 
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the author's name not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  The author makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  * 
  16.  * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 
  17.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE 
  18.  * AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 
  19.  * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
  20.  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
  21.  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  * 
  23.  * The author's current employer has no connection with this software, as it
  24.  * was written before being employed at Sun.  The following address is for 
  25.  * contacting the author only and does not imply any responsibility on the 
  26.  * behalf of Sun Microsystems.
  27.  * 
  28.  * Contact the author at:
  29.  *     Brian Warkentine  (brianw@Sun.COM)
  30.  *     Sun Microsystems
  31.  *     2550 Garcia Avenue
  32.  *     Mountain View, Ca 94043-1100
  33.  *
  34.  */
  35.  
  36. #include <X11/X.h>
  37. #include <X11/Intrinsic.h>
  38. #include <X11/StringDefs.h>
  39. #include <math.h>
  40. #include "xrobots.h"
  41.  
  42. extern Widget sonic_command;
  43.  
  44. void
  45. sonic_action()
  46. {
  47.   static Arg arg = { XtNsensitive, False};
  48.   if(!game_active) return;
  49.   XtSetValues(sonic_command,&arg,1);
  50.   sonic_screwdriver();
  51. }
  52.  
  53. void
  54. reset_sonic_button()
  55. {
  56.   static Arg arg = { XtNsensitive, True };
  57.   XtSetValues(sonic_command,&arg,1);
  58. }
  59.  
  60. /*ARGSUSED*/
  61. XtActionProc
  62. do_nothing_action(w,event,params,num_params)
  63.   Widget w;
  64.   XEvent *event;
  65.   String *params;
  66.   Cardinal *num_params;
  67. {
  68.   /* do nothing */
  69. }
  70.  
  71.  
  72. /*----------------------------------------------------------------------*/
  73.  
  74.  
  75. int 
  76. determine_direction(button_x,button_y)
  77.   int button_x,button_y;
  78. {
  79. /* 
  80.  * Given the mouse's x&y position, this routine determines the direction
  81.  * relative to the player, and returns the result coded into a int.
  82.  */
  83.   float slope, invslope;
  84.   int direction = 0;
  85.   int coord_x = pos_to_coord(human_x) + CELLSIZE/2,
  86.       coord_y = pos_to_coord(human_y) + CELLSIZE/2;
  87.  
  88.   if( (abs(coord_x - button_x) < (CELLSIZE/2)+2) &&
  89.       (abs(coord_y - button_y) < (CELLSIZE/2)+2)) 
  90.     return(STILL);      /* cursor is directly over the player */ 
  91.  
  92.   if(button_x - coord_x != 0) {
  93.     slope = fabs((float)(button_y - coord_y) / (float)(button_x - coord_x)); 
  94.  
  95.     if( button_x > coord_x ) {            /* in coordinates 1 or 4 */
  96.       if( (slope < 2) && (human_x < MAXX) )
  97.         direction = RIGHT;
  98.     }
  99.     else                     /* in coordinates 2 or 3 */
  100.       if( (slope < 2) && (human_x > -1) )
  101.         direction = LEFT;
  102.   }
  103.  
  104.   if(button_y - coord_y != 0) {
  105.     invslope = fabs((float)(button_x - coord_x) / (float)(button_y - coord_y)); 
  106.  
  107.     if( button_y > coord_y ) {            /* in coordinates 1 or 2 */
  108.       if( (invslope < 2) && (human_y < MAXY) )
  109.         direction |= DOWN;
  110.     }
  111.  
  112.     else                     /* in coordinates 3 or 4 */
  113.       if( (invslope < 2) && (human_y > -1) )
  114.         direction |= UP;
  115.   }
  116.   return(direction);
  117. }
  118.  
  119. /*----------------------------------------------------------------------*/
  120.  
  121. static int
  122. get_next_position(diff_x, diff_y, mousex, mousey, params, num_params)
  123.   int *diff_x, *diff_y, mousex, mousey, num_params;
  124.   String *params;
  125. {
  126.   int direction;
  127.  
  128.   *diff_x = *diff_y = 0;
  129.  
  130.   if(!num_params) {    /* no parameters - the mouse was used pointer */
  131.  
  132.     direction = determine_direction(mousex,mousey);
  133.     if(!direction)  return -1;
  134.  
  135.     if(direction & UP)    *diff_y = -1;
  136.     if(direction & DOWN)  *diff_y = 1;
  137.     if(direction & LEFT)  *diff_x = -1;
  138.     if(direction & RIGHT) *diff_x = 1;
  139.  
  140.     return 0;
  141.   } 
  142.  
  143.   while(num_params--) {
  144.       /* else pull the direction out of the parameters. */
  145.  
  146.     if(!strcmp("right",*(params+num_params)))    *diff_x = 1;
  147.     if(!strcmp("left", *(params+num_params)))    *diff_x = -1;
  148.     if(!strcmp("up",   *(params+num_params)))    *diff_y = -1;
  149.     if(!strcmp("down", *(params+num_params)))    *diff_y = 1;
  150.   }
  151.     return 0;
  152. }
  153.  
  154. /*----------------------------------------------------------------------*/
  155.  
  156.  
  157. /*ARGSUSED*/
  158. XtActionProc
  159. move_action(w,event,params,num_params)
  160.   Widget w;
  161.   XButtonEvent *event;
  162.   String *params;
  163.   Cardinal *num_params;
  164. {
  165. /* 
  166.  *  Called to move the player's icon.  This action can be called 
  167.  *  when a mouse button is pressed or when a key is pressed.
  168.  */
  169.   int diff_x, diff_y;
  170.   int num_wasted;
  171.  
  172.   if(!game_active) return;
  173.  
  174.   if(get_next_position(&diff_x, &diff_y, event->x, event->y,
  175.                         params, *num_params))
  176.     return;
  177.  
  178.   last_human_x = human_x;
  179.   last_human_y = human_y;
  180.  
  181.   if( can_go(human_x+diff_x,human_y+diff_y) ) {
  182.     human_x += diff_x;
  183.     human_y += diff_y;
  184.     num_wasted = chase(0);
  185.     show_movement();
  186.     add_score(num_wasted);
  187.     if(!num_robots)
  188.       new_level();
  189.     else
  190.       display_possible_moves();
  191.     auto_teleport();
  192.     pointer_moved((Widget)0,(caddr_t)0,event);
  193.   }
  194.   XFlush(display);
  195. }
  196.  
  197.  
  198.  
  199. /*ARGSUSED*/
  200. XtActionProc
  201. jump_action(w,event,params,num_params)
  202.   Widget w;
  203.   XButtonEvent *event;
  204.   String *params;
  205.   Cardinal *num_params;
  206. {
  207. /* 
  208.  * don't just move once, move until it can't go any farther.
  209.  */
  210.   int diff_x, diff_y;
  211.   int num_wasted;
  212.  
  213.   if(!game_active) return;
  214.  
  215.   if(get_next_position(&diff_x, &diff_y, event->x, event->y,
  216.                         params, *num_params))
  217.     return;
  218.  
  219.   if(! can_go(human_x+diff_x,human_y+diff_y) ) 
  220.     return;
  221.  
  222.   while( can_go(human_x+diff_x,human_y+diff_y) ) {
  223.     last_human_x = human_x;
  224.     last_human_y = human_y;
  225.     human_x += diff_x;
  226.     human_y += diff_y;
  227.     num_wasted = chase(0);
  228.     if(showjumps)
  229.       show_movement();
  230.     add_score(num_wasted);
  231.     if(!num_robots) 
  232.       break;
  233.     XFlush(display);
  234.   }
  235.   if(!num_robots)
  236.     new_level();
  237.   else 
  238.     if(!showjumps)
  239.       display_level();
  240.   display_possible_moves();
  241.   auto_teleport();
  242.   pointer_moved((Widget)0,(caddr_t)0,event);
  243.   XFlush(display);
  244. }
  245.  
  246.  
  247.  
  248. /*ARGSUSED*/
  249. XtActionProc
  250. go_here_action(w,event,params,num_params)
  251.   Widget w;
  252.   XButtonEvent *event;
  253.   String *params;
  254.   Cardinal *num_params;
  255. {
  256. /* 
  257.  * This action causes player's icon to try to go to a spot in the 
  258.  * play area.  It stops if a move cannot be made.
  259.  */
  260.   int direction;
  261.   int tmp_human_x, tmp_human_y;
  262.   int num_wasted;
  263.  
  264.   if(!game_active) return;
  265.  
  266.   while(direction = determine_direction(event->x,event->y)) {
  267.     if(direction == STILL) break;
  268.     tmp_human_x = human_x;
  269.     tmp_human_y = human_y;
  270.  
  271.     if(direction & UP)    tmp_human_y--;
  272.     if(direction & DOWN)  tmp_human_y++;
  273.     if(direction & LEFT)  tmp_human_x--;
  274.     if(direction & RIGHT) tmp_human_x++;
  275.  
  276.     if( !can_go(tmp_human_x,tmp_human_y) ) 
  277.       break;
  278.     last_human_x = human_x;
  279.     last_human_y = human_y;
  280.     human_x = tmp_human_x;
  281.     human_y = tmp_human_y;
  282.     num_wasted = chase(0);
  283.     if(showjumps)
  284.       show_movement();
  285.     add_score(num_wasted);
  286.     if(!num_robots)
  287.       break;
  288.     if(spiffy) 
  289.       pointer_moved((Widget)0,(caddr_t)0,event);
  290.     XFlush(display);
  291.   }
  292.   if(!num_robots)
  293.       new_level();
  294.   else
  295.     if(!showjumps)
  296.       display_level();
  297.   display_possible_moves();
  298.   auto_teleport();
  299.   pointer_moved((Widget)0,(caddr_t)0,event);
  300.   XFlush(display);
  301. }
  302.  
  303.  
  304.  
  305. /*ARGSUSED*/
  306. XtEventHandler
  307. pointer_moved(w, closure, event)
  308.   Widget w;
  309.   caddr_t closure;
  310.   XPointerMovedEvent *event;
  311. {
  312.   if(game_active) 
  313.     /* could probably suck up any other pointer motion events here... */
  314.     update_pointer( determine_direction(event->x,event->y) );
  315. }
  316.  
  317.